/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.mahumLogs.beans;

import com.mahumLogs.backedbeans.Domain;
import com.mahumLogs.backedbeans.Etudiant;
import com.mahumLogs.backedbeans.Log;
import com.mahumLogs.backedbeans.LogID;
import com.mahumLogs.backedbeans.LogsCalendarDate;
import com.mahumLogs.backedbeans.TopSite;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import javax.annotation.Resource;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.UserTransaction;
/**
 *
 * @author Kalast
 */
 
/**
 *
 * @author Kalast
 */
@Named
@SessionScoped
public class LogsBean implements Serializable{
    
    public static class EtudiantLogs{

        public long time;
        public String ip;
        public String domaine;
        public String url;

        public String getTime(){
            Date d = new Date(time);
            DateFormat df = new SimpleDateFormat("H:mm:ss");
            return df.format(d);
        }
        
        public String getIp() {
            return ip;
        }
        
        public String getDomaine() {
            return domaine;
        }

        public String getUrl() {
            return url;
        }
    }
    
    @PersistenceContext
    private EntityManager em;
    
    @Resource
    private UserTransaction tx;

    @Inject
    private TopSitesBean topSiteBean;
    private ArrayList<Log> logs;
    
    private int yearSelected;
    private int monthSelected;
    private int daySelected;
    private int hourSelected;
    
    private int viewSelected;
    private String viewMode;
    private String viewName;
    
    private List<Log> listeLogFilter;
    
    private Etudiant etudiantSelected;
    private int idEtudiantSelected;

    public LogsBean() {
        logs = new ArrayList();
        listeLogFilter = new ArrayList();
        viewName = "Top sites";
    }

    public Etudiant getEtudiantSelected() {
        return etudiantSelected;
    }

    public void setEtudiantSelected(Etudiant etudiantSelected) {
        this.etudiantSelected = etudiantSelected;
    }
    
    public void removeDomaineFilterStudent(){
        this.topSiteBean.setDomainSelected(null);
        changeEtudiantSelectedByID(idEtudiantSelected);
    }
    
    public void removeHourFilterStudent(){
        this.hourSelected = -1;
        changeEtudiantSelectedByID(idEtudiantSelected);
    }
    
    public void changeEtudiantSelectedByID(int id) {
        idEtudiantSelected = id;
        this.etudiantSelected = em.find(Etudiant.class, id);
        String query = "SELECT l.TIME, l.IP, l.DOMAINE, l.URL FROM log l"
                + " JOIN machine m ON m.IP LIKE l.IP"
                + " JOIN etudiant e ON m.FK_ETUDIANT = e.IDPERSONNE"
                + " WHERE l.TIME BETWEEN " + this.getTimeStartSelected() + " AND " + this.getTimeEndSelected()
                + " AND e.IDPERSONNE=" + id;
        if(this.topSiteBean.getDomainSelected() != null){
            query += " AND l.DOMAINE LIKE '" + this.topSiteBean.getDomainSelected() + "'";
        }
        
        query += " ORDER BY l.TIME ASC";
        
        System.out.println("query = " + query);
        
        this.logs.clear();
        Log l;
        LogID logid;
        List<Object[]> list = (List<Object[]>) this.em.createNativeQuery(query).getResultList();
        for (Object[] objects : list) {
            l = new Log();
            logid = new LogID();
            logid.time = Long.valueOf(objects[0].toString());
            l.setID(logid);
            l.setIp(objects[1].toString());
            l.setDomaine(objects[2].toString());
            l.setUrl(objects[3].toString());
            this.logs.add(l);
        }
    }

    public int getYearSelected() {
        return yearSelected;
    }

    public void setYearSelected(int yearSelected) {
        this.yearSelected = yearSelected;
    }

    public int getMonthSelected() {
        return monthSelected;
    }

    public void setMonthSelected(int monthSelected) {
        this.monthSelected = monthSelected;
    }

    public int getDaySelected() {
        return daySelected;
    }

    public void setDaySelected(int daySelected) {
        this.daySelected = daySelected;
    }

    public int getHourSelected() {
        return hourSelected;
    }

    public void setHourSelected(int hourSelected) {
        this.hourSelected = hourSelected;
        this.topSiteBean.majTopSite();
    }

    public void resetState(){
        logs.clear();
        listeLogFilter.clear();
    }
    
    public List<Log> getListeLogFilter() {
        return listeLogFilter;
    }

    public void setListeLogFilter(List<Log> listeLogFilter) {
        this.listeLogFilter = listeLogFilter;
    }

    public String getViewMode() {
        return viewMode;
    }

    public void setViewMode(String viewMode) {
        this.viewMode = viewMode;
    }

    public int getViewSelected() {
        return viewSelected;
    }

    public void setViewSelected(int viewSelected) {
        if(viewSelected == 1){
            viewName = "Logs";
        } else if(viewSelected == 2){
            viewName = "Top sites";
        } else if(viewSelected == 3){
            viewName = "Top utilisateurs";
        }
        
        this.viewSelected = viewSelected;
    }

    public String getViewName() {
        return viewName;
    }

    public void setViewName(String viewName) {
        this.viewName = viewName;
    }
    
    public void handleChangeHour(){
        if(this.hourSelected < 0){
            this.viewSelected = 2;
        }
        System.err.println("Change Hour " + this.hourSelected);
        majLogsAtHour();
        this.topSiteBean.majTopSite();
        listeLogFilter = logs;
    }
    
    public void handleChange(){
        System.err.println("Change " + this.hourSelected);
        if(this.viewSelected == 1){
            if(this.viewMode != null){
                switch (this.viewMode) {
                    case "hour":
                        majLogsAtHour();
                        break;
                }
            }
        } else if(this.viewSelected == 2){
            if(this.viewMode != null){
                topSiteBean.majTopSite();
            }
        }
        listeLogFilter = logs;
    }
    
    public int getNbPagesAtHour(){
        GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal.set(Calendar.YEAR, this.yearSelected);
        cal.set(Calendar.MONTH, this.monthSelected - 1);
        cal.set(Calendar.DATE, this.daySelected);
        cal.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        
        GregorianCalendar cal2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal2.set(Calendar.YEAR, this.yearSelected);
        cal2.set(Calendar.MONTH, this.monthSelected - 1);
        cal2.set(Calendar.DATE, this.daySelected);
        cal2.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        cal2.set(Calendar.MINUTE, 59);
        cal2.set(Calendar.SECOND, 59);
        cal2.set(Calendar.MILLISECOND, 999);
        
        Object count = this.em.createQuery("SELECT COUNT(l) FROM Log l WHERE l.atTime.time >= " + cal.getTimeInMillis() + " AND l.atTime.time <= " + cal2.getTimeInMillis()).getSingleResult();        
        return (int)(Float.valueOf(count.toString()) / 100f);
    }

    public List<Log> getLogs() {
        return logs;
    }
    
    public void majLogsAtHour(){
        GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal.set(Calendar.YEAR, this.yearSelected);
        cal.set(Calendar.MONTH, this.monthSelected - 1);
        cal.set(Calendar.DATE, this.daySelected);
        cal.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        
        GregorianCalendar cal2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal2.set(Calendar.YEAR, this.yearSelected);
        cal2.set(Calendar.MONTH, this.monthSelected - 1);
        cal2.set(Calendar.DATE, this.daySelected);
        cal2.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        cal2.set(Calendar.MINUTE, 59);
        cal2.set(Calendar.SECOND, 59);
        cal2.set(Calendar.MILLISECOND, 999);
        
        String query = "SELECT l.TIME, e.NOM, e.PRENOM, l.IP, l.DOMAINE, l.URL, l.REQUESTSIZE, l.MIMETYPE, e.IDPERSONNE FROM log l"
                + " LEFT JOIN machine m ON m.IP LIKE l.IP"
                + " LEFT JOIN etudiant e ON m.FK_ETUDIANT = e.IDPERSONNE"
                + " WHERE l.TIME BETWEEN " + this.getTimeStartSelected() + " AND " + this.getTimeEndSelected();
        
        System.out.println("query = " + query);        
        this.logs.clear();
        Log l;
        LogID logid;
        List<Object[]> list = (List<Object[]>) this.em.createNativeQuery(query).getResultList();
        for (Object[] objects : list) {
            l = new Log();
            logid = new LogID();
            logid.time = Long.valueOf(objects[0].toString());
            l.setID(logid);
            if(objects[1] != null){
                l.setNomEtudiant(objects[1].toString());
            }
            if(objects[2] != null){
                l.setPrenomEtudiant(objects[2].toString());
            }
            
            l.setIp(objects[3].toString());
            if(objects[4] != null){
                l.setDomaine(objects[4].toString());
            }
            
            l.setUrl(objects[5].toString());
            l.setRequestSize(Long.valueOf(objects[6].toString()));
            
            if(objects[7] != null){
                l.setMimeType(objects[7].toString());
            }
            
            if(objects[8] != null){
                l.setIdEtudiant(Integer.valueOf(objects[8].toString()));
            }
            this.logs.add(l);
        }
    }
    
    public long getTimeStartSelected(){
        GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal.set(Calendar.YEAR, this.yearSelected);
        cal.set(Calendar.MONTH, this.monthSelected - 1);
        cal.set(Calendar.DATE, this.daySelected);
        
        if(this.hourSelected > 0){
            cal.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        } else {
            cal.set(Calendar.HOUR_OF_DAY, 0);
        }
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        
        System.out.println(this.daySelected + "/" + this.monthSelected + "/" + this.yearSelected + " " + cal.get(Calendar.HOUR_OF_DAY) + ":" + 0 + ":" + 0 + ":" + 0);
        
        return cal.getTimeInMillis();
    }
    
    public long getTimeEndSelected(){
        GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal.set(Calendar.YEAR, this.yearSelected);
        cal.set(Calendar.MONTH, this.monthSelected - 1);
        cal.set(Calendar.DATE, this.daySelected);
        if(this.hourSelected >= 0){
            cal.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        } else {
            cal.set(Calendar.HOUR_OF_DAY, 23);
        }
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        System.out.println(this.daySelected + "/" + this.monthSelected + "/" + this.yearSelected + " " + cal.get(Calendar.HOUR_OF_DAY) + ":" + 59 + ":" + 59 + ":" + 999);
        return cal.getTimeInMillis();
    }
    
    public List<List<String>> getLogsEtudiantAtTime(){
        logs.clear();
        GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal.set(Calendar.YEAR, this.yearSelected);
        cal.set(Calendar.MONTH, this.monthSelected - 1);
        cal.set(Calendar.DATE, this.daySelected);
        cal.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        
        GregorianCalendar cal2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Paris"));
        cal2.set(Calendar.YEAR, this.yearSelected);
        cal2.set(Calendar.MONTH, this.monthSelected - 1);
        cal2.set(Calendar.DATE, this.daySelected);
        cal2.set(Calendar.HOUR_OF_DAY, this.hourSelected);
        cal2.set(Calendar.MINUTE, 59);
        cal2.set(Calendar.SECOND, 59);
        cal2.set(Calendar.MILLISECOND, 999);
        
        String query = "SELECT l.TIME, m.IDMACHINE, m.LIBELLE, l.IP, l.URL, l.REQUESTSIZE, l.REQUESTTIME FROM `log` l" +
                        " JOIN machine m ON l.IP LIKE m.IP" +
                        " JOIN etudiant e ON m.FK_ETUDIANT = e.IDPERSONNE" +
                        " WHERE l.TIME BETWEEN " + cal.getTimeInMillis() + " AND " + cal2.getTimeInMillis() +
                        " ORDER BY l.TIME ASC";
        
        em.createNativeQuery(query).getResultList();
        return null;
    }
    
    public List<LogsCalendarDate> getHoursInDayLog() {
        ArrayList<LogsCalendarDate> lcds = new ArrayList<>();
        Query query = em.createQuery("SELECT ts FROM TopSite ts WHERE ts.annee=:yearl AND ts.mois=:monthl AND ts.jour=:dayl GROUP BY ts.heure ORDER BY ts.heure ASC");
        query.setParameter("yearl", this.yearSelected);
        query.setParameter("monthl", this.monthSelected);
        query.setParameter("dayl", this.daySelected);

        List<TopSite> topSites = query.getResultList();

        for (TopSite ts : topSites) {
            lcds.add(new LogsCalendarDate(ts));
        }

        return lcds;
    }
    
    public List<String[]> getTopSiteTotal(){
        System.out.println("Start requete domain top sites total");    
        List<String[]> results = em.createNativeQuery("SELECT DISTINCT `DOMAINE` as dom, (SELECT COUNT(*) FROM `log` WHERE `DOMAINE` LIKE dom) as nb_log FROM `log`").getResultList();
        return results;
    }
    
    public List<Domain> getTopSiteMonth(){
        return null;
    }
    
    public List<Domain> getTopSiteDay(){
        return null;
    }
}
